Tengo un problema al leer un archivo justo después de agregarle líneas. Parece que al insertar menos de 913742 caracteres, está bien, pero al insertar más de 914534 caracteres, las siguientes líneas se leen como líneas en blanco (el búfer aún está vacío).
import { promises as fs } from "fs"; const filepath = 'any.file'; const readChunk = async (start: number, end: number) => { const buffer = Buffer.from("".padStart(end, " ")); const fd = await fs.open(filepath, "r"); await fd.read({ buffer, offset: 0, position: start, length: end }); await fd.datasync(); await fd.close(); return buffer.toString(); }; const append = async (line: string) => { const fd = await fs.open(filepath, "a"); await fd.appendFile(chunk); await fd.datasync(); await fd.close(); };Mi prueba de broma:
import faker from "faker"; const fakeUser = (): UserDatas => ({ id: Math.round(Math.random() * MAX_SAFE_INTEGER), message: faker.lorem.paragraphs(), }); const fakeUsers = (count: number) => Array.from({ length: count }).map(fakeUser); describe("large amount of data", () => { it("should accept thousand lines", async () => { const instance = getInstance(); await instance.append( fakeUsers(faker.datatype.number({ min: 9000, max: 10000 })) ); expect(await instance.count()).toBeGreaterThan(8000); }); });La salida:
● BsonFile › large amount of data › should accept thousand lines expect(received).toBeGreaterThan(expected) Expected: > 8000 Received: 1364 178 | fakeUsers(faker.datatype.number({ min: 9000, max: 10000 })) 179 | ); > 180 | expect(await instance.count()).toBeGreaterThan(8000); | ^ 181 | }); 182 | }); 183 | });La razón por la que no puedo contar más 1364 es que el archivo no genera ningún dato.
Además, esperaba que fd.datasync() resolviera mi problema, pero no lo hace: ¿debería dejarlo ahí? ¿Es esto útil?
En el código a continuación, está agregando "trozo", pero no puedo ver que está definiendo o configurando "trozo" en ninguna parte del código, ¿debería ser "línea" que se pasa a la función? ¿Podría ser éste el problema?
const append = async (line: string) => { const fd = await fs.open(filepath, "a"); await fd.appendFile(chunk); await fd.datasync(); await fd.close(); };Deberia ser:
const append = async (line: string) => { const fd = await fs.open(filepath, "a"); await fd.appendFile(line); await fd.datasync(); await fd.close(); };No entiendo tu código de prueba. ¿Qué hace getInstance()?
filehandle.datasync() fuerza todas las operaciones de E/S actualmente en cola asociadas con el archivo al estado de finalización de E/S sincronizadas del sistema operativo.
No debería necesitar ejecutar esta función para ver los datos, solo está allí para garantizar que los búferes se vacíen para que no pierda datos en caso de falla de energía o hardware.
Consulte también https://nodejs.org/api/fs.html#filehandledatasync y https://man7.org/linux/man-pages/man2/fdatasync.2.html para obtener más información.